package ece1779.ec2;

import java.io.IOException;

import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.Date;
import java.util.Vector;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.cloudwatch.*;
import com.amazonaws.services.cloudwatch.model.*;

public class ManagerUI extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
		response.setContentType("text/html");
        PrintWriter out = response.getWriter();
		Config config = new Config((BasicAWSCredentials)getServletContext().getAttribute("AWSCredentials"), out, getServletContext().getRealPath("/"));
		String growTreshold = request.getParameter("CPUForGrow");
		String shrinkTreshold = request.getParameter("CPUForShrink");
		String growMultiplier = request.getParameter("RatioForExpand");
		String shrinkMultiplier = request.getParameter("RatioForShrink");
		
		try {
			if (growTreshold.length() > 0)
				config.data.growTreshold = Integer.parseInt(growTreshold.trim());
			if (shrinkTreshold.length() > 0)
				config.data.shrinkTreshold = Integer.parseInt(shrinkTreshold.trim());
			if (growMultiplier.length() > 0)
				config.data.growMultiplier = Integer.parseInt(growMultiplier.trim());
			if (shrinkMultiplier.length() > 0)
				config.data.shrinkMultiplier = Integer.parseInt(shrinkMultiplier.trim());
			config.storeConfig();
			out.println("Config Updated<br>");
		} catch (NumberFormatException e) {
			out.println("Form values must be integers<br>");
		}
		doGet(request, response);
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException
    {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        Config config = new Config((BasicAWSCredentials)getServletContext().getAttribute("AWSCredentials"), out, getServletContext().getRealPath("/"));
        
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Enviroment Variables</title>");
        out.println("</head>");
        out.println("<body>");
		out.println("2221");
		// we need to create a form for the user to submit their configuration for autoscalling policies
		out.print("<h4>Custom Autos-scaling policy settings</h4>");
		out.print("<form action='/ece1779/servlet/ManagerUI' method='post'>");
		out.print("CPU threshold for growing the worker pool <input type='text' name='CPUForGrow' value='" + config.data.growTreshold+ "'><br />");
		out.print("CPU threshold for shrinking the worker pool <input type='text' name='CPUForShrink' value='" + config.data.shrinkTreshold+ "'><br />");
		out.print("Ratio for expansion <input type='text' name='RatioForExpand' value='" + config.data.growMultiplier+ "'><br />");
		out.print("Ratio for shrink <input type='text' name='RatioForShrink' value='" + config.data.shrinkMultiplier+ "'><br />");
		out.print("<input type='submit' value='Send'>");
		out.print("<input type='reset'>");
		out.print("</form>");
		
		// output a table to display all running instances
        cloudWatchExample(out);
        // add a start instance link at the end of table
        out.print("<tr>");
		out.print("<td></td>");   
		out.print("<td><a href='StartInstance'>Start a New Instance</a></td>");
		out.print("</tr>");
		
		
        out.println("</body>");
        out.println("</html>");
		
    }
    
       
    void cloudWatchExample(PrintWriter out) throws IOException {
    	
    	
    	BasicAWSCredentials awsCredentials = (BasicAWSCredentials)getServletContext().getAttribute("AWSCredentials");
    	
		
    	
        AmazonCloudWatch cw = new AmazonCloudWatchClient(awsCredentials);
        
   
        try {

        	ListMetricsRequest listMetricsRequest = new ListMetricsRequest();
        	listMetricsRequest.setMetricName("CPUUtilization");
        	listMetricsRequest.setNamespace("AWS/EC2");
        	ListMetricsResult result = cw.listMetrics(listMetricsRequest);
        	java.util.List<Metric> 	metrics = result.getMetrics();
			out.print("<h4>Currently Running Instances</h4>");
			out.print("<table border = '1'>");
			out.print("<tr>");
			out.print("<td>Instance ID</td>");
			out.print("<td>CPU Utilization in Percentage</td>");
			out.print("<td>Action</td>");
			out.print("</tr>");
        	for (Metric metric : metrics) {
        		String namespace = metric.getNamespace();
        		String metricName = metric.getMetricName();
        		List<Dimension> dimensions = metric.getDimensions();
            	GetMetricStatisticsRequest statisticsRequest = new GetMetricStatisticsRequest();
            	statisticsRequest.setNamespace(namespace);
            	statisticsRequest.setMetricName(metricName);
            	statisticsRequest.setDimensions(dimensions);
            	Date endTime = new Date();
            	Date startTime = new Date();
				// set the period between start time to end time to be 3 mins. Sometimes the datapoint is not shown if the period is set too small
            	startTime.setTime(endTime.getTime()- 180000);
            	statisticsRequest.setStartTime(startTime);
            	statisticsRequest.setEndTime(endTime);
            	statisticsRequest.setPeriod(60);
            	Vector<String>statistics = new Vector<String>();
            	statistics.add("Maximum");
            	statisticsRequest.setStatistics(statistics);
            	GetMetricStatisticsResult stats = cw.getMetricStatistics(statisticsRequest);
				
				if (dimensions.isEmpty()==false) {
					// we also do not want to print out images with imageid and instance type
					if (dimensions.get(0).getName().equals("InstanceId")) {
						// make sure we do not give the user to option to shutdown the ManagerUI instance itself
						if (dimensions.get(0).getValue().equals("i-07dd7863")==false) {
						// also make sure that the instance is running by checking the stats
							
							if (stats.getDatapoints().size()>=1) {
							//if (stats.toString().equals("{Label: CPUUtilization, }") == false) {
								out.print("<tr>");
								out.print("<td>"+dimensions.get(0).getValue()+"</td>");
								out.print("<td>"+stats.getDatapoints().get(0).getMaximum()+"</td>");
								out.print("<td><a href='StopInstance?"+dimensions.get(0).getValue()+"'>Stop Instance</a></td>");
								out.println("</tr>");
							}
							
						}
					}
				}
            	
        		
            }
			
        	
        } catch (AmazonServiceException ase) {
            out.println("Caught an AmazonServiceException, which means your request made it "
                    + "to Amazon EC2, but was rejected with an error response for some reason.");
            out.println("Error Message:    " + ase.getMessage());
            out.println("HTTP Status Code: " + ase.getStatusCode());
            out.println("AWS Error Code:   " + ase.getErrorCode());
            out.println("Error Type:       " + ase.getErrorType());
            out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            out.println("Caught an AmazonClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with EC2, "
                    + "such as not being able to access the network.");
            out.println("Error Message: " + ace.getMessage());
        }
    }
    
}